﻿using EMoney.IStock.Client.DataAccess.Yjjx;
using EMoney.IStock.Client.Framework;
using EMoney.IStock.Client.Models;
using EMoney.IStock.Client.Models.Yjjx;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Dynamic;

namespace EMoney.IStock.Client.Business.Yjjx
{
    /// <summary>
    /// 业绩精选业务处理类
    /// </summary>
    public class YjjxBll
    {
        private object objStat = new object();
        private object objRecord = new object();
        private object objPool = new object();
        private object objRate = new object();
        private object objYjjxDate = new object();

        private const string STAT_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Yjjx.YjjxBll.Stat";
        private const string RECORD_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Yjjx.YjjxBll.Record";
        private const string POOL_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Yjjx.YjjxBll.PoolKey";
        private const string RATE_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Yjjx.YjjxBll.Rate";
        private const string DATE_MEMCACHED_KEY = "EMoney.IStock.Client.Business.Yjjx.YjjxBll.Date";

        /// <summary>
        /// 获取近两周日期
        /// </summary>
        /// <returns></returns>
        public List<KeyValue> GetRecentDate()
        {
            DateTime dtNow = DateTime.Now;
            string key = string.Concat(DATE_MEMCACHED_KEY,".",StringHelper.FormatDateTime(dtNow));

            List<KeyValue> list = CacheManager.RedisCache.Get<List<KeyValue>>(key);

            if (list == null || list.Count == 0)
            {
                lock (objYjjxDate)
                {
                    list = CacheManager.RedisCache.Get<List<KeyValue>>(key);

                    if (list == null || list.Count == 0)
                    {                        
                        DateTime dtMax = dtNow;
                        DateTime dtMin = dtNow.AddDays(-14);
                        string value = string.Empty;
                        list = new List<KeyValue>();

                        while (dtMin.Date <= dtMax.Date)
                        {
                            switch (dtMax.DayOfWeek)
                            {
                                case DayOfWeek.Saturday:
                                case DayOfWeek.Sunday:
                                    dtMax = dtMax.AddDays(-1);
                                    continue;
                                default:
                                    break;
                            }

                            if (dtMax.Date == dtNow.Date)
                            {
                                value = string.Concat("今天，",StringHelper.FormatDayOfWeek(dtMax.DayOfWeek));
                            }
                            else if (dtMax.Date == dtNow.AddDays(-1).Date)
                            {
                                value = string.Concat("昨天，", StringHelper.FormatDayOfWeek(dtMax.DayOfWeek));
                            }
                            else
                            {
                                value = string.Concat(StringHelper.FormatDateTime(dtMax,"M-d"), "，", StringHelper.FormatDayOfWeek(dtMax.DayOfWeek));
                            }

                            list.Add(new KeyValue() {
                                key = StringHelper.FormatDateTime(dtMax),
                                value = value
                            });

                            dtMax = dtMax.AddDays(-1);
                        }

                        CacheManager.DefaultCache.Set<List<KeyValue>>(key, list, 60 * 24);
                    }
                }
            }

            return list;
        }

        /// <summary>
        /// 获取入选期间去重后股票个数
        /// </summary>
        /// <param name="blType"></param>
        /// <returns></returns>
        public int GetInStockCount(string blType)
        {
            return new YjjxDal().GetInStockCount(blType);
        }

        /// <summary>
        /// 获取入选期间股票最大收益大于10的个数
        /// </summary>
        /// <param name="blType"></param>
        /// <returns></returns>
        public int GetInStockLChangeRatioCount(string blType)
        {
            return new YjjxDal().GetInStockLChangeRatioCount(blType);
        }

        /// <summary>
        /// 获取业绩精选股票比例数据
        /// </summary>
        /// <param name="blType"></param>
        /// <returns></returns>
        public List<CircleRate> GetCircleRate(string blType)
        {
            string key = string.Concat(RATE_MEMCACHED_KEY, ".", blType);
            List<CircleRate> list = CacheManager.RedisCache.Get<List<CircleRate>>(key);

            if (list != null && list.Count > 0)
            {
                return list;
            }
            else
            {
                try
                {
                    lock (objRate)
                    {
                        list = CacheManager.RedisCache.Get<List<CircleRate>>(key);

                        if (list == null)
                        {
                            list = new List<CircleRate>();

                            int total = GetInStockCount(blType);
                            int lCount = GetInStockLChangeRatioCount(blType);

                            double ratio = (double)lCount / total * 100;

                            list.Add(new CircleRate()
                            {
                                Name = blType,
                                Value = ratio
                            });

                            list.Add(new CircleRate()
                            {
                                //HToName = blType,
                                Value = 100 - ratio
                            });

                            CacheManager.RedisCache.Set<List<CircleRate>>(key, list, 60);
                        }

                        return list;
                    }
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取业绩精选股票比例数据失败");

                    return null;
                }
            }
        }

        /// <summary>
        /// 获取业绩精选策略战绩
        /// </summary>
        /// <returns></returns>
        public List<VM_PERFORMANCE_CHANGE_POOL_GOODRATIO> GetRecord(string sortFlag = "lchangeratio", string sortType = "desc")
        {
            List<VM_PERFORMANCE_CHANGE_POOL_GOODRATIO> list = CacheManager.RedisCache.Get<List<VM_PERFORMANCE_CHANGE_POOL_GOODRATIO>>(RECORD_MEMCACHED_KEY);

            if (list != null && list.Count > 0)
            {
                list = list.AsQueryable().OrderBy(string.Concat(sortFlag, " ", sortType)).ToList();

                return list;
            }
            else
            {
                try
                {
                    lock (objRecord)
                    {
                        list = CacheManager.RedisCache.Get<List<VM_PERFORMANCE_CHANGE_POOL_GOODRATIO>>(RECORD_MEMCACHED_KEY);

                        if (list == null)
                        {
                            YjjxDal dal = new YjjxDal();

                            list = dal.GetRecord();

                            if (list != null)
                            {
                                CacheManager.RedisCache.Set<List<VM_PERFORMANCE_CHANGE_POOL_GOODRATIO>>(RECORD_MEMCACHED_KEY, list, 60);
                            }
                        }
                    }

                    return list;
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取业绩精选策略战绩失败");

                    return null;
                }
            }
        }

        /// <summary>
        /// 获取业绩精选股票池
        /// </summary>
        /// <param name="inDate"></param>
        /// <returns></returns>
        public List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE> GetPool(DateTime inDate, string sortFlag, string sortType, string bltype)
        {
            string key = string.Concat(POOL_MEMCACHED_KEY, ".", inDate.ToString("yyyy-MM-dd"));

            List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE> list = CacheManager.RedisCache.Get<List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE>>(key);

            if (list == null || list.Count == 0)
            {
                try
                {
                    lock (objPool)
                    {
                        list = CacheManager.RedisCache.Get<List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE>>(key);

                        if (list == null)
                        {
                            YjjxDal dal = new YjjxDal();
                            DateTime dtNow = DateTime.Now;

                            list = dal.GetPool(inDate);

                            if (list == null)
                            {
                                list = new List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE>();
                            }

                            if (inDate.Date == dtNow.Date && dtNow.TimeOfDay >= new TimeSpan(8, 0, 0) && dtNow.TimeOfDay <= new TimeSpan(16, 0, 0))
                            {
                                CacheManager.RedisCache.Set<List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE>>(key, list, 10);
                            }
                            else
                            {
                                CacheManager.RedisCache.Set<List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE>>(key, list, 60);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取业绩精选股票池失败");

                    return null;
                }
            }

            if (list != null && list.Count > 0)
            {
                if (bltype != "0")
                {
                    switch (bltype)
                    {
                        case "1":
                            bltype = "续盈";
                            break;
                        case "2":
                            bltype = "扭亏";
                            break;
                        case "3":
                            bltype = "减亏";
                            break;
                        default:
                            bltype = string.Empty;
                            break;
                    }

                    if (!string.IsNullOrEmpty(bltype))
                    {
                        list = list.FindAll(obj => obj.BLType == bltype);
                    }
                }

                if (list != null && list.Count > 0)
                {
                    if (sortFlag.Equals("Cline",StringComparison.OrdinalIgnoreCase))
                    {
                        List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE> listFirst = new List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE>();
                        List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE> listOther = new List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE>();
                        switch (sortType)
                        {
                            case "desc":
                                listFirst = list.FindAll(lst => lst.Cline == 1);    //获取首次发出B点的数据
                                listOther = list.FindAll(lst => lst.Cline != 1);
                                break;
                            case "asc":
                                listFirst = list.FindAll(lst => lst.Cline == -1);   //获取首次发出S点的数据
                                listOther = list.FindAll(lst => lst.Cline != -1);
                                break;
                            default:
                                break;
                        }

                        if (listFirst == null)
                        {
                            listFirst = new List<VM_PERFORMANCE_CHANGE_POOL_MAXDATE>();
                        }
                        if (listOther != null && listOther.Count > 0)
                        {
                            listOther = listOther.AsQueryable().OrderBy(string.Concat(sortFlag, " ", sortType)).ToList();
                        }

                        list.Clear();
                        list.AddRange(listFirst);
                        list.AddRange(listOther);
                    }
                    else
                    {
                        list = list.AsQueryable().OrderBy(string.Concat(sortFlag, " ", sortType)).ToList();
                    }
                }
            }

            return list;
        }

        /// <summary>
        /// 获取业绩精选统计信息
        /// </summary>
        /// <param name="tradeDate"></param>
        /// <returns></returns>
        public PERFORMANCE_Change_Stat GetStat(DateTime tradeDate)
        {
            string key = string.Concat(STAT_MEMCACHED_KEY,".",tradeDate.ToString("yyyy-MM-dd"));
            PERFORMANCE_Change_Stat stat = CacheManager.RedisCache.Get<PERFORMANCE_Change_Stat>(key);

            if (stat != null)
            {
                return stat;
            }
            else
            {
                try
                {
                    lock (objStat)
                    {
                        stat = CacheManager.RedisCache.Get<PERFORMANCE_Change_Stat>(key);

                        if (stat == null)
                        {
                            YjjxDal dal = new YjjxDal();

                            stat = dal.GetStat(tradeDate);

                            if (stat == null)
                            {
                                stat = new PERFORMANCE_Change_Stat();
                            }

                            if (tradeDate.Date == DateTime.Now.Date)
                            {
                                CacheManager.RedisCache.Set<PERFORMANCE_Change_Stat>(key, stat, 10);
                            }
                            else
                            {
                                CacheManager.RedisCache.Set<PERFORMANCE_Change_Stat>(key, stat, 60);
                            }
                        }
                    }

                    return stat;
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogger.Error(ex, "获取业绩精选统计信息失败");

                    return null;
                }
            }
        }
    }
}
